package edu.the.last.fft;

import edu.the.last.modell.Music;

/**
 * class detecting the notes singed by de user
 * 
 * @author albertcsani
 * 
 */
public class Frequency {
	private double fftBytes[];
	private int sapmleRate;
	private double frequency[];
	private int bufferSize;
	private MusicalSound ms = new MusicalSound();
	private FFT fft;
	private double doubleBufferSize;
	private double lowest = 82.375, highest = 1046.0; // the lowest and the
														// highest sounds human
														// can sing...

	public Frequency(Music music) {
		doubleBufferSize = music.getInterval();
		sapmleRate = (int) music.getFormat().getSampleRate();
		byte audioBytes[] = music.getAudioBytes();
		int frames = audioBytes.length;
		fftBytes = new double[frames];
		for (int i = 0; i < frames; i++) {
			fftBytes[i] = audioBytes[i];
		}
	}

	/**
	 * detects and returns the notes singed
	 * 
	 * @param bufferSize
	 *            the sizse of the buffer to use
	 * @return the frequancys
	 * @throws Exception
	 *             Throws an exception if the real and imaginary inputs are of
	 *             different sizes or if less than three input samples are
	 *             provided.
	 */
	public int[] getSounds() throws Exception {
		this.bufferSize = (int) Math.floor(sapmleRate * doubleBufferSize);
		frequency = new double[fftBytes.length / bufferSize + 1];
		int sounds[] = new int[fftBytes.length / bufferSize + 1];
		int k = 0;
		for (int i = 0; i < fftBytes.length; i += bufferSize) {
			if ((fftBytes.length - i) > 3) {
				double fftWindow[] = new double[Math.min(bufferSize, fftBytes.length - i)];
				for (int j = 0; j < bufferSize && (i + j) < fftBytes.length; j++) {
					fftWindow[j] = fftBytes[i + j];
				}
				fft = new FFT(fftWindow, null, false, false);
				double bins[] = fft.getBinLabels(44100);
				double magnitudes[] = fft.getMagnitudeSpectrum();
				int ind = 0;
				for (int j = 1; j < magnitudes.length; j++) {
					if (magnitudes[j] > magnitudes[ind] && bins[j] > lowest && bins[j] < highest) {
						ind = j;
					}
				}
				sounds[k] = ms.getSound(bins[ind], bins[1]);
				frequency[k++] = bins[ind];
			}
		}

		return sounds;
	}
}
